package cn.iocoder.yudao.framework.common.util.algorithm.asymmetric;

import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

@Slf4j
public class RSAUtils {
    private static final Provider PROVIDER = new BouncyCastleProvider();


    // 生成RSA密钥对
    public static KeyPair generateRSAKeyPair() {
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", PROVIDER);
            keyPairGenerator.initialize(2048);
            return keyPairGenerator.generateKeyPair();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // 使用私钥签名数据
    public static byte[] signData(String privateKeyBase64, byte[] data) {
        return signData(java.util.Base64.getDecoder().decode(privateKeyBase64), data);
    }

    // 使用私钥签名数据
    public static byte[] signData(byte[] privateKeyBytes, byte[] data) {
        try {
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA", PROVIDER);
            PrivateKey privateKey = keyFactory.generatePrivate(keySpec);

            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initSign(privateKey);
            signature.update(data);
            return signature.sign();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // 使用公钥验证签名
    public static boolean verifySignature(String publicKeyBase64, String signatureBase64, byte[] data) {
        return verifySignature(java.util.Base64.getDecoder().decode(publicKeyBase64),
                java.util.Base64.getDecoder().decode(signatureBase64), data);
    }

    // 使用公钥验证签名
    public static boolean verifySignature(byte[] publicKeyBytes, byte[] signature, byte[] data) {
        try {
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA", PROVIDER);
            PublicKey publicKey = keyFactory.generatePublic(keySpec);

            Signature verifier = Signature.getInstance("SHA256withRSA");
            verifier.initVerify(publicKey);
            verifier.update(data);
            return verifier.verify(signature);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}
